package com.wutong.hotfixdemo

import android.Manifest.permission
import android.os.Bundle
import android.os.Environment
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.PermissionUtils
import com.blankj.utilcode.util.ToastUtils
import dalvik.system.PathClassLoader
import java.io.File

class MainActivity : AppCompatActivity() {

    companion object{
        const val dexName = "NewDexPrintAppName.dex"
//        const val dexName = "NewDexPrintFunctionName.dex"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        checkPermissHotFix()

        val txtView = findViewById<TextView>(R.id.main_txt)
        txtView.setOnClickListener {
            checkPermissHotFix()

            val appUtil = AppUtils()
            val newStr = AppUtils.getAppName() + "\n" + appUtil.getStingAppName() + "\n" + appUtil.getFinalAppName()
            txtView.setText(newStr)
        }
    }

    /** 检查存储权限获取情况，然后开启修复或索要权限 */
    fun checkPermissHotFix(){
        if(PermissionUtils.isGranted(permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE)){
            hotFix()//热修复
        }else{//获取权限
            PermissionUtils.permission(permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE).request()
        }
    }

    /** 热修复 */
    private fun hotFix(){
        val dexFile = FileUtils.getFileByPath(Environment.getExternalStorageDirectory().absolutePath + "/${dexName}")
        if(dexFile.exists()) {
            //成功案例 Huawei P10 Android8.0 EMUI8.0
            //查询资料得知，Android8.0之后，DexClassLoader和PathClassLoader无区别
            //降级targetSdk后，允许在外部存储读取dex文件，但是仍然无法实际修复，仅是不报错

            //失败案例 荣耀 V20 Android10 鸿蒙2.0

            //失败案例 Xiaomi MIX2S Android10 MIUI12.5

            //失败案例 Huawei Mate10 Android10 鸿蒙2.0
            // E/System: java.io.IOException: No original dex files found for dex location /storage/emulated/0/NewDexPrintAppName.dex
            // 将热修复文件位置改为私有路径后不报错

            //失败案例 魅族 17Pro Android11 Flyme9.3.1
            // E/System: Unable to load dex file: /storage/emulated/0/NewDexPrintAppName.dex
            // E/System: java.io.IOException: No original dex files found for dex location (arm64) /storage/emulated/0/NewDexPrintAppName.dex
            // 将热修复文件位置改为私有路径后不报错

            //失败案例 Realme Q3 Android12 realme3.0
            // E/System: java.io.IOException: Failed to open dex files from /storage/emulated/0/NewDexPrintAppName.dex because: Unable to open '/storage/emulated/0/NewDexPrintAppName.dex' : Permission denied
            // 将热修复文件位置改为私有路径后不报错

            //失败案例 Xiaomi 13 Android13 MIUI14
            // E  Unable to load dex file: /storage/emulated/0/NewDexPrintAppName.dex
            // E  java.io.IOException: Failed to open dex files from /storage/emulated/0/NewDexPrintAppName.dex because: Unable to open '/storage/emulated/0/NewDexPrintAppName.dex' : Permission denied
            // 将热修复文件位置改为私有路径后不报错

            Hotfix.patch(applicationContext, dexFile.path, "com.wutong.hotfixdemo.AppUtils")
        }



//        val privateFile = File(Environment.getExternalStorageDirectory().absolutePath + "/Android/data/com.wutong.hotfixdemo/cache/${dexName}")
////        val privateFile = File(Environment.getExternalStorageDirectory().absolutePath + "/Android/data/com.wutong.hotfixdemo/files/${dexName}")
//        if(privateFile.exists()) {
//            Hotfix.patch(this, privateFile.path, "com.wutong.hotfixdemo.AppUtils")
//        }else{
//            ToastUtils.showLong("存在与否：${privateFile.exists()} \n 私有路径：${privateFile.path}")
//        }


//        //自行拷贝文件至如下路径后，Xiaomi13、Mate10无法成功。且无法使用代码拷贝文件
//        val privateFile = File("/data/data/com.wutong.hotfixdemo/app_dex/${dexName}")
//        //FileUtils.copy(dexFile, privateFile)
//        if(privateFile.exists()) {
//            Hotfix.patch(applicationContext, privateFile.path, "com.wutong.hotfixdemo.AppUtils")
//        }else{
//            ToastUtils.showLong("存在与否：${privateFile.exists()} \n 私有路径：${privateFile.path}")
//        }
    }
}
